#include "napi/native_api.h"
#include <cstdlib>
#include <string.h>
#include <string>
#include <vector>
#include <unistd.h>
#include <thread>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <fcntl.h>
#include <chrono>
#include <atomic>
#include "hilog/log.h"
#include "leaf.h"

#define logger_info(fmt, args...) OH_LOG_Print(LOG_APP, LOG_INFO, 0x1234, "debug", fmt, ##args)
#define BUFFER_SIZE 2048

struct RetryConfig {
    // 协议过滤开关
    bool filter_non_tcp = true;
    // 基础重试配置
    int max_retries = 3;
    int retry_interval_ms = 1000;
    int socket_timeout_ms = 5000;
    // TCP特有配置
    int tcp_connect_retries = 5;
    int tcp_handshake_timeout_ms = 3000;
    // UDP特有配置
    int udp_bind_retries = 3;
};

struct IPRange {
    in_addr_t start;
    in_addr_t end;
    bool enabled;
};

struct EventData {
    std::string domain;
    uint32_t ip;
    std::string host;
    int port;
    uint32_t latency;
};

static int g_tunFd;
static std::atomic<bool> thread_running(false);
static std::atomic<bool> udp_enabled(false);
static int udp_socket_pair[2] = {0};
static std::thread* udp_thread = nullptr;
static std::thread* tcp_thread = nullptr;
static std::vector<IPRange> ip_ranges;
static std::atomic<bool> ip_filter_enabled(false);
static std::string host;
static RetryConfig retry_config;
static std::mutex ip_ranges_mutex;
static napi_threadsafe_function dns_event_callback = nullptr;
static napi_threadsafe_function gateway_event_callback = nullptr;
static napi_threadsafe_function http_event_callback = nullptr;
static std::vector<Gateway> gateway_pool;
static write_packet_t write_packet = nullptr;
static std::string http_secret_key = "default-secret-key";
static napi_threadsafe_function g_js_packet_callback = nullptr;
static napi_threadsafe_function g_js_callback = nullptr;

//http事件回调函数
void handle_http_event(const HttpSessionStamp* stamp, void* userdata) {
    if (!http_event_callback) return;
    
    HttpSessionStamp* stamp_copy = new HttpSessionStamp(*stamp);
    napi_call_threadsafe_function(http_event_callback, stamp_copy, napi_tsfn_blocking);
}

//http会话
static void http_event_handler(napi_env env, napi_value js_callback, 
                             void* context, void* data) {
    auto* stamp = static_cast<HttpSessionStamp*>(data);
    
    napi_value js_event;
    napi_create_object(env, &js_event);
    
    // 转换所有字段
    napi_value val;
    napi_create_uint32(env, stamp->session_id, &val);
    napi_set_named_property(env, js_event, "sessionId", val);
    
    napi_create_string_utf8(env, stamp->client_ip, NAPI_AUTO_LENGTH, &val);
    napi_set_named_property(env, js_event, "clientIp", val);
    
    napi_value undefined;
    napi_get_undefined(env, &undefined);
    napi_call_function(env, undefined, js_callback, 1, &js_event, nullptr);
    
    delete stamp;
}

// DNS事件回调处理
void handle_dns_event(const char* domain, uint32_t ip, void* userdata) {
    if (!dns_event_callback) return;
    
    napi_status status;
    // 准备回调数据
    struct EventData {
        const char* domain;
        uint32_t ip;
    };
    
    EventData* event_data = new EventData{domain, ip};
    
    // 调用线程安全函数
    status = napi_call_threadsafe_function(
        dns_event_callback,
        event_data,
        napi_tsfn_blocking
    );
    
    if (status != napi_ok) {
        logger_info("zjx--Failed to call DNS event callback");
        delete event_data;
    }
}

// 网关事件回调处理
void handle_gateway_event(const char* host, int port, uint32_t latency, void* userdata) {
    if (!gateway_event_callback) return;
    
    napi_status status;
    // 准备回调数据
    struct EventData {
        const char* host;
        int port;
        uint32_t latency;
    };
    
    EventData* event_data = new EventData{host, port, latency};
    
    // 调用线程安全函数
    status = napi_call_threadsafe_function(
        gateway_event_callback,
        event_data,
        napi_tsfn_blocking
    );
    
    if (status != napi_ok) {
        logger_info("zjx--Failed to call gateway event callback");
        delete event_data;
    }
}

// 线程安全回调的处理函数
void call_callback(napi_env env, napi_value js_callback, void* context, void* data) {
    if (!env || !js_callback) return;
    
    // 转换数据
    auto* event_data = static_cast<EventData*>(data);
    
    // 创建对象
    napi_value js_event;
    napi_create_object(env, &js_event);
    
    if (context == &dns_event_callback) {
        // DNS事件
        napi_value domain, ip;
        napi_create_string_utf8(env, event_data->domain.c_str(), NAPI_AUTO_LENGTH, &domain);
        char ip_str[16];
        inet_ntop(AF_INET, &event_data->ip, ip_str, sizeof(ip_str));
        napi_create_string_utf8(env, ip_str, NAPI_AUTO_LENGTH, &ip);
        
        napi_set_named_property(env, js_event, "domain", domain);
        napi_set_named_property(env, js_event, "ip", ip);
        napi_value type_value;
        napi_create_string_utf8(env, "dns", NAPI_AUTO_LENGTH, &type_value);
        napi_set_named_property(env, js_event, "type", type_value);
    } else {
        // 网关事件
        napi_value host, port, latency;
        napi_create_string_utf8(env, event_data->host.c_str(), NAPI_AUTO_LENGTH, &host);
        napi_create_int32(env, event_data->port, &port);
        napi_create_uint32(env, event_data->latency, &latency);
        
        napi_set_named_property(env, js_event, "host", host);
        napi_set_named_property(env, js_event, "port", port);
        napi_set_named_property(env, js_event, "latency", latency);
        const char* typeStr = event_data->port == 0 ? "remove" : "update";
        napi_value typeValue;
        napi_create_string_utf8(env, typeStr, NAPI_AUTO_LENGTH, &typeValue);
        napi_set_named_property(env, js_event, "type", typeValue);
    }
    
    // 调用JavaScript回调
    napi_value undefined;
    napi_get_undefined(env, &undefined);
    napi_value result;
    napi_call_function(env, undefined, js_callback, 1, &js_event, &result);
    
    delete event_data;
}

// 设置套接字超时
bool set_socket_timeout(int fd, int timeout_ms) {
    struct timeval tv;
    tv.tv_sec = timeout_ms / 1000;
    tv.tv_usec = (timeout_ms % 1000) * 1000;
    
    if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) {
        logger_info("zjx--Set SO_RCVTIMEO failed : %{public}d", errno);
        return false;
    }
    
    if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))) {
        logger_info("zjx--Set SO_SNDTIMEO failed : %{public}d", errno);
        return false;
    }
    return true;
}

// TCP连接重试（带超时）
bool tcp_connect_with_retry(int sockfd, const struct sockaddr* addr, socklen_t addrlen) {
    // 设置为非阻塞模式先尝试连接
    int flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

    int ret = connect(sockfd, addr, addrlen);
    if (ret == 0) {
        fcntl(sockfd, F_SETFL, flags); // 恢复阻塞模式
        return true;
    }

    if (errno != EINPROGRESS) {
        return false;
    }

    fd_set writefds;
    FD_ZERO(&writefds);
    FD_SET(sockfd, &writefds);

    struct timeval tv;
    tv.tv_sec = retry_config.tcp_handshake_timeout_ms / 1000;
    tv.tv_usec = (retry_config.tcp_handshake_timeout_ms % 1000) * 1000;

    ret = select(sockfd + 1, nullptr, &writefds, nullptr, &tv);
    if (ret <= 0) {
        return false; // 超时或错误
    }

    int error = 0;
    socklen_t len = sizeof(error);
    getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
    fcntl(sockfd, F_SETFL, flags); // 恢复阻塞模式
    
    return error == 0;
}

// 创建TCP连接（完整重试）
bool create_tcp_connection(const char* host, int port) {
    struct sockaddr_in server_addr = {0};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    
    if (inet_pton(AF_INET, host, &server_addr.sin_addr) <= 0) {
        logger_info("zjx--Invalid address : %{public}s", host);
        return false;
    }

    for (int i = 0; i < retry_config.tcp_connect_retries; ++i) {
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0) {
            logger_info("zjx--Socket creation failed : (attempt %{public}d): %{public}d", i+1, errno);
            continue;
        }

        set_socket_timeout(sock, retry_config.socket_timeout_ms);

        if (tcp_connect_with_retry(sock, (struct sockaddr*)&server_addr, sizeof(server_addr))) {
            logger_info("zjx--TCP connection established to : %{public}s:%{public}d", host, port);
            return true; 
        }

        close(sock);
        logger_info("zjx--TCP connect attempt %{public}d failed to %{public}s:%{public}d", i+1, host, port);
        
        if (i < retry_config.tcp_connect_retries - 1) {
            std::this_thread::sleep_for(
                std::chrono::milliseconds(retry_config.retry_interval_ms));
        }
    }
    return false;
}

// UDP套接字对创建带重试
bool create_udp_socket_pair(int socket_pair[2]) {
    for (int i = 0; i < retry_config.udp_bind_retries; ++i) {
        if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socket_pair) == 0) {
            set_socket_timeout(socket_pair[0], retry_config.socket_timeout_ms);
            set_socket_timeout(socket_pair[1], retry_config.socket_timeout_ms);
            return true;
        }
        logger_info("zjx--UDP socketpair attempt : %{public}d failed: %{public}d", i+1, errno);
        std::this_thread::sleep_for(
            std::chrono::milliseconds(retry_config.retry_interval_ms));
    }
    return false;
}

// 检查IP是否在指定范围内
bool is_ip_in_range(in_addr_t ip) {
    if (!ip_filter_enabled || ip_ranges.empty()) {
        return true;
        }
    uint32_t host_ip = ntohl(ip);
    // 反转字节顺序
    uint32_t reversed_ip = ((host_ip & 0xFF000000) >> 24) |
                          ((host_ip & 0x00FF0000) >> 8) |
                          ((host_ip & 0x0000FF00) << 8) |
                          ((host_ip & 0x000000FF) << 24);
    
    std::lock_guard<std::mutex> lock(ip_ranges_mutex);
    for (const auto& range : ip_ranges) {
        uint32_t range_start = ntohl(range.start);
        uint32_t range_end = ntohl(range.end);
        logger_info("zjx--ip Checking range: %{public}u.%{public}u.%{public}u.%{public}u - %{public}u.%{public}u.%{public}u.%{public}u against %{public}u.%{public}u.%{public}u.%{public}u",
                   (range_start >> 24) & 0xFF, (range_start >> 16) & 0xFF,
                   (range_start >> 8) & 0xFF, range_start & 0xFF,
                   (range_end >> 24) & 0xFF, (range_end >> 16) & 0xFF,
                   (range_end >> 8) & 0xFF, range_end & 0xFF,
                   (reversed_ip >> 24) & 0xFF, (reversed_ip >> 16) & 0xFF,
                   (reversed_ip >> 8) & 0xFF, host_ip & 0xFF);
        
        if (reversed_ip >= range_start && reversed_ip <= range_end) {
            logger_info("zjx--ip MATCHED: %{public}u.%{public}u.%{public}u.%{public}u is in range",
                      (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
                      (ip >> 8) & 0xFF, ip & 0xFF);
            return true;
        }
    }
        return false;
}

// 从数据包中提取目标IP
in_addr_t extract_dest_ip(const uint8_t* data, size_t len) {
    // 验证IPv4头部最小长度
    if (data == nullptr || len < 20) {
        logger_info("zjx--ip Invalid packet: data=%{public}p, len=%{public}zu", data, len);
        return 0;
    }
    // 验证IP版本和协议类型
    uint8_t version = data[0] >> 4;
    uint8_t protocol = data[9];
    if (version != 4 || protocol != 6) {
        logger_info("zjx--ip Unsupported packet: version=%{public}u, protocol=%{public}u", version, protocol);
        return 0;
    }
    // 3. 检查IP头部长度是否足够（避免越界）
    uint8_t ihl = data[0] & 0x0F;
    if (len < (size_t)(ihl * 4)) {
        logger_info("zjx--ip Invalid IP header length: ihl=%{public}u, len=%{public}zu", ihl, len);
        return 0;
    }
    
    in_addr_t dest_ip;
    memcpy(&dest_ip, data + 16, 4);
    dest_ip = ntohl(dest_ip);
    logger_info("zjx--ip RAW extracted: %{public}u.%{public}u.%{public}u.%{public}u", 
               (dest_ip >> 24) & 0xFF,
               (dest_ip >> 16) & 0xFF,
               (dest_ip >> 8) & 0xFF,
               dest_ip & 0xFF);
    bool isInRange = is_ip_in_range(dest_ip);
    if (isInRange) {
        logger_info("zjx--ip Captured valid: %{public}u.%{public}u.%{public}u.%{public}u", 
                   (dest_ip >> 24) & 0xFF,
                   (dest_ip >> 16) & 0xFF,
                   (dest_ip >> 8) & 0xFF,
                   dest_ip & 0xFF);
        return dest_ip;
    } else {
        logger_info("zjx--ip Captured BUT NOT in range: %{public}u.%{public}u.%{public}u.%{public}u", 
                   (dest_ip >> 24) & 0xFF,
                   (dest_ip >> 16) & 0xFF,
                   (dest_ip >> 8) & 0xFF,
                   dest_ip & 0xFF);
        return 0;  // 不在范围内返回0
    }
}

// 带超时和错误处理的读取
int safe_read(int fd, uint8_t* buffer, size_t size) {
    fd_set read_fds;
    FD_ZERO(&read_fds);
    FD_SET(fd, &read_fds);
    
    struct timeval tv;
    tv.tv_sec = retry_config.socket_timeout_ms / 1000;
    tv.tv_usec = (retry_config.socket_timeout_ms % 1000) * 1000;
    
    int ret = select(fd + 1, &read_fds, nullptr, nullptr, &tv);
    if (ret <= 0) {
        logger_info("zjx--Select returned %{public}d, errno: %{public}d", ret, errno);
        return ret;
    }

    // 读取数据并检查返回值
    ssize_t bytes_read = read(fd, buffer, size);
    if (bytes_read <= 0) {
        logger_info("zjx--Read returned %zd, errno: %{public}d", bytes_read, errno);
        return bytes_read;
    }
    // 验证数据有效性
    bool all_zero = true;
    for (size_t i = 0; i < std::min((size_t)20, (size_t)bytes_read); i++) {
        if (buffer[i] != 0) {
            all_zero = false;
            break;
        }
    }
    if (all_zero) {
        logger_info("zjx--Warning: Read all-zero packet of size %{public}zd", bytes_read);
    }
    
    return bytes_read;
}

// TCP转发线程
void tcp_forward() {
    logger_info("zjx--TCP forward thread started");
    uint8_t buffer[BUFFER_SIZE] = {0};
    
    while (thread_running) {
        int ret = safe_read(g_tunFd, buffer, sizeof(buffer));
        if (ret <= 0) {
            if (ret == 0) {
                logger_info("zjx--TCP read timeout");
            } else if (errno != EAGAIN) {
                logger_info("zjx--TCP read error : %{public}d", errno);
                // 严重错误时重建连接
                if (errno == ECONNRESET || errno == ENETDOWN) {
                    std::this_thread::sleep_for(
                        std::chrono::milliseconds(retry_config.retry_interval_ms * 2));
                }
            }
        // 新增协议检查
        uint8_t ip_proto = buffer[9]; // IPv4头部第10字节是协议类型
            logger_info("zjx--Packet protocol (proto=%{public}d)", ip_proto);
        if (retry_config.filter_non_tcp && ip_proto != 6) { // 6=TCP
            logger_info("zjx--Discard non-TCP packet(proto=%{public}d)", ip_proto);
                if (ip_proto == 17 && udp_enabled) { // 17=UDP
                // 如果是UDP包且UDP已启用，转发到UDP通道
                write(udp_socket_pair[1], buffer, ret);
            }
            continue; // 直接丢弃非TCP包
            }
        }

        in_addr_t dest_ip = extract_dest_ip(buffer, ret);
        if (is_ip_in_range(dest_ip)) {
            input_packet(buffer, ret);
        }

        // 带重试的写入
        for (int i = 0; i < retry_config.max_retries; ++i) {
            input_packet(buffer, ret);
            break;
            logger_info("zjx--TCP input_packet retry : %{public}d", i+1);
            std::this_thread::sleep_for(
                std::chrono::milliseconds(retry_config.retry_interval_ms));
        }
    }
    logger_info("zjx--TCP forward thread exited");
}

// UDP转发线程带重试机制
void udp_forward() {
    logger_info("zjx--UDP forward thread started");
    uint8_t buffer[BUFFER_SIZE] = {0};
    
    while (udp_enabled) {
        int ret = safe_read(udp_socket_pair[0], buffer, sizeof(buffer));
        if (ret <= 0) {
            if (ret == 0) logger_info("zjx--UDP read timeout");
            else if (errno != EAGAIN) logger_info("UDP read error : %{public}d", errno);
            continue;
        }

        in_addr_t dest_ip = extract_dest_ip(buffer, ret);
        if (is_ip_in_range(dest_ip)) {
            for (int i = 0; i < retry_config.max_retries; ++i) {
                input_packet(buffer, ret);
                break;
                logger_info("zjx--UDP input_packet retry : %{public}d", i+1);
                std::this_thread::sleep_for(
                    std::chrono::milliseconds(retry_config.retry_interval_ms));
            }
        }
    }
    logger_info("zjx--UDP forward thread exited");
}

static void call_js_packet_callback(napi_env env, napi_value js_callback, void* context, void* data) {
    std::vector<uint8_t>* packet = static_cast<std::vector<uint8_t>*>(data);
    if (!env || !packet) return;

    // 1. 创建ArrayBuffer
    napi_value arraybuffer;
    void* arraybuffer_data;
    napi_create_arraybuffer(env, packet->size(), &arraybuffer_data, &arraybuffer);
    memcpy(arraybuffer_data, packet->data(), packet->size());

    // 2.创建Uint8Array
    napi_value uint8array;
    napi_create_typedarray(env, napi_uint8_array, packet->size(), arraybuffer, 0, &uint8array);

    // 3. 调用JS回调
    napi_value global, result;
    napi_get_global(env, &global);
    napi_call_function(env, global, js_callback, 1, &uint8array, &result);

    // 4. 释放内存
    delete packet;
}

void safe_write_packet(const uint8_t* data, size_t len) {
    for (int i = 0; i < retry_config.max_retries; ++i) {
        ssize_t ret = write(g_tunFd, data, len);
        if (ret == (ssize_t)len) {
            logger_info("zjx--Packet written successfully");
            return;
        }
        logger_info("zjx--Write retry : %{public}d, errno: %{public}d", i+1, errno);
        std::this_thread::sleep_for(
            std::chrono::milliseconds(retry_config.retry_interval_ms));
    }
    logger_info("zjx--Failed to write packet after %{public}d retries", retry_config.max_retries);
}

// 添加IP范围
static napi_value nativeAddIPRange(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char start_ip[16] = {0}, end_ip[16] = {0};
    size_t len = 0;
    napi_get_value_string_utf8(env, args[0], start_ip, sizeof(start_ip), &len);
    napi_get_value_string_utf8(env, args[1], end_ip, sizeof(end_ip), &len);

    in_addr_t start = inet_addr(start_ip);
    in_addr_t end = inet_addr(end_ip);
    
    if (start == INADDR_NONE || end == INADDR_NONE) {
        napi_throw_error(env, "-3001", "Invalid IP address format");
        return nullptr;
    }
    
    if (ntohl(start) > ntohl(end)) {  // 注意比较时转换为主机字节序
        napi_throw_error(env, "EINVAL", "Start IP must be <= End IP");
        return nullptr;
    }

    {
        std::lock_guard<std::mutex> lock(ip_ranges_mutex);
        ip_ranges.push_back({start, end, true});
    }
    logger_info("zjx--ip add range: %{public}s-%{public}s (host order: %{public}u.%{public}u.%{public}u.%{public}u-%{public}u.%{public}u.%{public}u.%{public}u)",
               start_ip, end_ip,
               (ntohl(start) >> 24) & 0xFF, (ntohl(start) >> 16) & 0xFF,
               (ntohl(start) >> 8) & 0xFF, ntohl(start) & 0xFF,
               (ntohl(end) >> 24) & 0xFF, (ntohl(end) >> 16) & 0xFF,
               (ntohl(end) >> 8) & 0xFF, ntohl(end) & 0xFF);
    return nullptr;
}

// 清除所有IP范围
static napi_value nativeClearIPRanges(napi_env env, napi_callback_info info) {
    ip_ranges.clear();
    logger_info("zjx--Cleared all IP ranges");
    return nullptr;
}

// 启用/禁用IP过滤
static napi_value nativeSetIPRangeFilter(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    bool enable;
    napi_get_value_bool(env, args[0], &enable);
    
    ip_filter_enabled = enable;
    logger_info("zjx--iP filter : %{public}s", enable ? "enabled" : "disabled");
    return nullptr;
}

// 设置重试配置
static napi_value nativeSetRetryConfig(napi_env env, napi_callback_info info) {
    size_t argc = 3;
    napi_value args[3];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    int32_t max_retries, retry_interval, socket_timeout;
    napi_get_value_int32(env, args[0], &max_retries);
    napi_get_value_int32(env, args[1], &retry_interval);
    napi_get_value_int32(env, args[2], &socket_timeout);

    retry_config.max_retries = max_retries > 0 ? max_retries : 3;
    retry_config.retry_interval_ms = retry_interval > 0 ? retry_interval : 1000;
    retry_config.socket_timeout_ms = socket_timeout > 0 ? socket_timeout : 5000;

    logger_info("zjx--Retry config updated : max_retries=%{public}d, interval=%{public}dms, timeout=%{public}dms",
               retry_config.max_retries, retry_config.retry_interval_ms, 
               retry_config.socket_timeout_ms);
    return nullptr;
}


// 增强版nativeStart
static napi_value nativeStart(napi_env env, napi_callback_info info) {
    napi_status status;
    size_t argc = 3;
    napi_value args[3] = {nullptr};

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取参数
    int32_t fd;
    status = napi_get_value_int32(env, args[0], &fd);
    if (status != napi_ok) {
        napi_throw_error(env, "-1001", "Invalid fd value");
        return nullptr;
    }

    char *buf;
    size_t length = 0;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &length);
    buf = length ? (char*)malloc(length+1) : strdup("");
    napi_get_value_string_utf8(env, args[1], buf, length+1, &length);
    host = std::string(buf);
    free(buf);
    
    int32_t port;
    if ((status = napi_get_value_int32(env, args[2], &port)) != napi_ok) {
        napi_throw_error(env, "-1001", "Invalid port value");
        return nullptr;
    }

    g_tunFd = fd;
    logger_info("zjx--Starting SOCKS proxy on fd : %{public}d@%{public}s:%{public}d", fd, host.c_str(), port);

    // 先建立TCP连接
    if (!create_tcp_connection(host.c_str(), port)) {
        napi_throw_error(env, "-1002", "Failed to establish TCP connection");
        return nullptr;
    }

    // 启动SOCKS协议
    for (int i = 0; i < retry_config.max_retries; ++i) {
        if (start_socks(safe_write_packet, host.c_str(), port)) {
            thread_running = true;
            tcp_thread = new std::thread(tcp_forward);
            logger_info("zjx--SOCKS proxy started successfully");
            return nullptr;
        }
        logger_info("zjx--SOCKS handshake retry : %{public}d", i+1);
        std::this_thread::sleep_for(
            std::chrono::milliseconds(retry_config.retry_interval_ms));
    }

    napi_throw_error(env, "-1003", "Failed to start SOCKS proxy");
    return nullptr;
}

static napi_value nativeEnableUdp(napi_env env, napi_callback_info info) {
    if (udp_enabled) return nullptr;

    if (!create_udp_socket_pair(udp_socket_pair)) {
        napi_throw_error(env, "-2001", "Failed to create UDP socket pair");
        return nullptr;
    }

    udp_enabled = true;
    udp_thread = new std::thread(udp_forward);
    logger_info("zjx--UDP proxy enabled");
    return nullptr;
}

static napi_value nativeDisableUdp(napi_env env, napi_callback_info info) {
    if (!udp_enabled) return nullptr;

    udp_enabled = false;
    close(udp_socket_pair[0]);
    close(udp_socket_pair[1]);
    udp_socket_pair[0] = udp_socket_pair[1] = 0;

    if (udp_thread) {
        if (udp_thread->joinable()) udp_thread->join();
        delete udp_thread;
        udp_thread = nullptr;
    }

    if (!thread_running && !tcp_thread) {
        thread_running = true;
        tcp_thread = new std::thread(tcp_forward);
    }
    
    logger_info("zjx--UDP proxy disabled");
    return nullptr;
}

static napi_value nativeStop(napi_env env, napi_callback_info info) {
    nativeDisableUdp(env, info);
    thread_running = false;

    if (tcp_thread) {
        if (tcp_thread->joinable()) tcp_thread->join();
        delete tcp_thread;
        tcp_thread = nullptr;
    }
    
    // 清理DNS回调
    if (dns_event_callback) {
        napi_release_threadsafe_function(dns_event_callback, napi_tsfn_abort);
        dns_event_callback = nullptr;
    }
    
    // 清理网关回调
    if (gateway_event_callback) {
        napi_release_threadsafe_function(gateway_event_callback, napi_tsfn_abort);
        gateway_event_callback = nullptr;
    }
    
    // 清理网关池
    gateway_pool.clear();
    
    logger_info("zjx--Proxy stopped");
    return nullptr;
}

static napi_value nativeGetPacketProtocol(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 验证参数
    if (argc < 1) {
        napi_throw_error(env, nullptr, "Expected 1 argument");
        return nullptr;
    }

    // 检查参数是否为Uint8Array
    bool is_typedarray;
    napi_is_typedarray(env, args[0], &is_typedarray);
    if (!is_typedarray) {
        napi_throw_error(env, nullptr, "Argument must be a Uint8Array");
        return nullptr;
    }

    // 获取信息数据
    napi_typedarray_type type;
    size_t length;
    void* data;
    napi_value arraybuffer;
    size_t byte_offset;
    napi_get_typedarray_info(env, args[0], &type, &length, &data, &arraybuffer, &byte_offset);

    // 校验类型
    if (type != napi_uint8_array) {
        napi_throw_error(env, nullptr, "Expected Uint8Array");
        return nullptr;
    }

    // 检查数据
    if (!data) {
        logger_info("zjx--nativeGetPacketProtocol ArrayBuffer data is NULL!");
        napi_throw_error(env, nullptr, "ArrayBuffer data is NULL");
        return nullptr;
    }

    // 协议检测
    int protocol = get_packet_protocol(static_cast<uint8_t*>(data), length);
    
    // 返回结果
    napi_value result;
    napi_create_int32(env, protocol, &result);
    return result;
}

static napi_value nativeSetPacketCallback(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 创建线程安全函数
    napi_value callback_name;
    napi_status status = napi_create_string_utf8(env, "PacketCallback", NAPI_AUTO_LENGTH, &callback_name);
    napi_create_threadsafe_function(
        env, args[0], nullptr, 
        callback_name,
        0, 1, nullptr, nullptr, nullptr,
        call_js_packet_callback, &g_js_callback
    );

    // 设置 Native 回调
    set_packet_callback([](const uint8_t* data, size_t len, void*) {
        logger_info("zjx--nativeSetPacketCallback: Packet callback invoked, len=%{public}zu", len);
        if (!data || len == 0) {
            logger_info("zjx--nativeSetPacketCallback: Invalid packet data (null or zero length)");
            return;
        }
        // 打印前20字节用于调试
        logger_info("zjx--nativeSetPacketCallback: Packet data (first 20 bytes):");
        for (size_t i = 0; i < (len > 20 ? 20 : len); ++i) {
            logger_info("zjx--nativeSetPacketCallback data [%{public}02zu]: 0x%{public}02x", i, data[i]);
        }
    auto* packet_copy = new std::vector<uint8_t>(data, data + len);
        logger_info("zjx--nativeSetPacketCallback: Created packet copy, size=%{public}zu", packet_copy->size());
    napi_status status = napi_call_threadsafe_function(
        g_js_callback,
        packet_copy,
        napi_tsfn_blocking
    );
    if (status != napi_ok) {
        logger_info("zjx--Failed to call packet callback, freeing data");
        delete packet_copy;
    }
}, nullptr);

    return nullptr;
}

// 设置本地DNS解析
static napi_value nativeSetLocalDNS(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 解析domain参数
    char domain[256] = {0};
    size_t domain_len;
    napi_get_value_string_utf8(env, args[0], domain, sizeof(domain), &domain_len);

    // 解析ip参数
    char ip_str[16] = {0};
    size_t ip_len;
    napi_get_value_string_utf8(env, args[1], ip_str, sizeof(ip_str), &ip_len);

    uint32_t ip = inet_addr(ip_str);
    if (ip == INADDR_NONE) {
        napi_throw_error(env, "EINVAL", "Invalid IP address format");
        return nullptr;
    }

    dns_set_local(domain, ip);
    logger_info("zjx--Set local DNS : %{public}s -> %{public}s", domain, ip_str);
    
    return nullptr;
}

// 添加上游DNS服务器
static napi_value nativeSetUpstreamDNS(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char dns_server[16] = {0};
    size_t len;
    napi_get_value_string_utf8(env, args[0], dns_server, sizeof(dns_server), &len);

    dns_set_upstream(dns_server);
    logger_info("zjx--Set upstream DNS : %{public}s", dns_server);
    
    return nullptr;
}

// 添加网关
static napi_value nativeAddGateway(napi_env env, napi_callback_info info) {
    size_t argc = 3;
    napi_value args[3];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 解析host
    char host[256] = {0};
    size_t host_len;
    napi_get_value_string_utf8(env, args[0], host, sizeof(host), &host_len);

    // 解析port
    int32_t port;
    napi_get_value_int32(env, args[1], &port);

    // 解析weight
    int32_t weight;
    napi_get_value_int32(env, args[2], &weight);

    Gateway gw = {
        .host = strdup(host),
        .port = port,
        .weight = static_cast<uint32_t>(weight),
        .latency = 0
    };
    
    gateway_add(&gw);
    logger_info("zjx--Added gateway : %{public}s:%{public}d (weight=%{public}d)", host, port, weight);
    
    return nullptr;
}

// 资源注册
static napi_value nativeRegisterResource(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char uri[512] = {0};
    size_t uri_len;
    napi_get_value_string_utf8(env, args[0], uri, sizeof(uri), &uri_len);

    char group[256] = {0};
    size_t group_len;
    napi_get_value_string_utf8(env, args[1], group, sizeof(group), &group_len);

    resource_register(uri, group);
    logger_info("zjx--Registered resource : %{public}s => %{public}s", uri, group);
    
    return nullptr;
}

// 资源请求
static napi_value nativeRequestResource(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char uri[512] = {0};
    size_t uri_len;
    napi_get_value_string_utf8(env, args[0], uri, sizeof(uri), &uri_len);

    const char* group = resource_locate(uri);
    if (group) {
        Gateway* gw = gateway_select();
        if (gw) {
            start_socks(write_packet, gw->host, gw->port);
            logger_info("zjx--Routing %{public}s via %{public}s (group: %{public}s)", uri, gw->host, group);
            
            // 返回选中的网关信息
            napi_value result;
            napi_create_object(env, &result);
            
            napi_value host, port;
            napi_create_string_utf8(env, gw->host, NAPI_AUTO_LENGTH, &host);
            napi_create_int32(env, gw->port, &port);
            
            napi_set_named_property(env, result, "host", host);
            napi_set_named_property(env, result, "port", port);
            
            return result;
        }
    }
    
    napi_throw_error(env, "ENOTFOUND", "No available gateway for resource");
    return nullptr;
}

// 获取当前网关状态
static napi_value nativeGetGateways(napi_env env, napi_callback_info info) {
    napi_value result;
    napi_create_array(env, &result);

    uint32_t index = 0;
    for (const auto& gw : gateway_pool) {
        napi_value item;
        napi_create_object(env, &item);
        
        napi_value host, port, weight;
        napi_create_string_utf8(env, gw.host, NAPI_AUTO_LENGTH, &host);
        napi_create_int32(env, gw.port, &port);
        napi_create_int32(env, gw.weight, &weight);
        
        napi_set_named_property(env, item, "host", host);
        napi_set_named_property(env, item, "port", port);
        napi_set_named_property(env, item, "weight", weight);
        
        napi_set_element(env, result, index++, item);
    }
    
    return result;
}

//移除网关
static napi_value nativeRemoveGateway(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char host[256] = {0};
    size_t len;
    napi_get_value_string_utf8(env, args[0], host, sizeof(host), &len);

    gateway_remove(host);
    logger_info("zjx--Removed gateway: %{public}s", host);
    return nullptr;
}

// 设置DNS事件回调
static napi_value nativeSetDnsEventCallback(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    if (argc < 1) {
        napi_throw_error(env, nullptr, "Missing callback function");
        return nullptr;
    }
    
    napi_valuetype valuetype;
    napi_typeof(env, args[0], &valuetype);
    if (valuetype != napi_function) {
        napi_throw_error(env, nullptr, "Callback must be a function");
        return nullptr;
    }
    
    // 释放之前的回调
    if (dns_event_callback) {
        napi_release_threadsafe_function(dns_event_callback, napi_tsfn_abort);
        dns_event_callback = nullptr;
    }
    
    // 创建新的线程安全函数
    napi_value dnsEventCallbackName;
    napi_create_string_utf8(env, "DNS Event Callback", NAPI_AUTO_LENGTH, &dnsEventCallbackName);
    napi_create_threadsafe_function(
        env,
        args[0],
        nullptr,
        dnsEventCallbackName,
        0,
        1,
        nullptr,
        nullptr,
        nullptr,
        call_callback,
        &dns_event_callback
    );
    
    // 设置leaf的回调
    dns_set_callback(handle_dns_event, nullptr);
    logger_info("zjx--Native Set Dns Event Callback");
    return nullptr;
}

// 设置网关事件回调
static napi_value nativeSetGatewayEventCallback(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    if (argc < 1) {
        napi_throw_error(env, nullptr, "Missing callback function");
        return nullptr;
    }
    
    napi_valuetype valuetype;
    napi_typeof(env, args[0], &valuetype);
    if (valuetype != napi_function) {
        napi_throw_error(env, nullptr, "Callback must be a function");
        return nullptr;
    }
    
    // 释放之前的回调
    if (gateway_event_callback) {
        napi_release_threadsafe_function(gateway_event_callback, napi_tsfn_abort);
        gateway_event_callback = nullptr;
    }
    
    // 创建新的线程安全函数
    napi_value gatewayCallbackName;
    napi_create_string_utf8(env, "Gateway Event Callback", NAPI_AUTO_LENGTH, &gatewayCallbackName);
    napi_create_threadsafe_function(
        env,
        args[0],
        nullptr,
        gatewayCallbackName,
        0,
        1,
        nullptr,
        nullptr,
        nullptr,
        call_callback,
        &gateway_event_callback
    );
    
    // 设置leaf的回调
    gateway_set_callback(handle_gateway_event, nullptr);
    logger_info("zjx--Native Set Gateway Event Callback");
    return nullptr;
}

// 更新网关延迟
static napi_value nativeUpdateGatewayLatency(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    char host[256] = {0};
    size_t host_len;
    napi_get_value_string_utf8(env, args[0], host, sizeof(host), &host_len);
    
    uint32_t latency;
    napi_get_value_uint32(env, args[1], &latency);
    
    gateway_update_latency(host, latency);
    logger_info("zjx--Native Update Gateway Latency");
    return nullptr;
}

//本地DNS解析函数
static napi_value nativeDnsResolveLocal(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char domain[256] = {0};
    size_t len;
    napi_get_value_string_utf8(env, args[0], domain, sizeof(domain), &len);

    uint32_t ip = dns_resolve_local(domain);
    
    char ip_str[16] = {0};
    inet_ntop(AF_INET, &ip, ip_str, sizeof(ip_str));
    
    napi_value result;
    napi_create_string_utf8(env, ip_str, NAPI_AUTO_LENGTH, &result);
    logger_info("zjx--Native Dns Resolve Local");
    return result;
}

//网关选择函数
static napi_value nativeGatewaySelect(napi_env env, napi_callback_info info) {
    Gateway* gw = gateway_select();
    if (!gw) {
        napi_throw_error(env, "ENOGATEWAY", "No available gateway");
        return nullptr;
    }

    napi_value result;
    napi_create_object(env, &result);
    
    napi_value host, port, weight, latency;
    napi_create_string_utf8(env, gw->host, NAPI_AUTO_LENGTH, &host);
    napi_create_int32(env, gw->port, &port);
    napi_create_uint32(env, gw->weight, &weight);
    napi_create_uint32(env, gw->latency, &latency);
    
    napi_set_named_property(env, result, "host", host);
    napi_set_named_property(env, result, "port", port);
    napi_set_named_property(env, result, "weight", weight);
    napi_set_named_property(env, result, "latency", latency);
    logger_info("zjx--Native Gateway Select");
    return result;
}

//资源定位函数
static napi_value nativeResourceLocate(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char uri[512] = {0};
    size_t len;
    napi_get_value_string_utf8(env, args[0], uri, sizeof(uri), &len);

    const char* group = resource_locate(uri);
    if (!group) {
        return nullptr;
    }
    
    napi_value result;
    napi_create_string_utf8(env, group, NAPI_AUTO_LENGTH, &result);
    logger_info("zjx--Native Resource Locate");
    return result;
}

// 启用HTTP分析
static napi_value nativeEnableHttpAnalysis(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    bool enable;
    napi_get_value_bool(env, args[0], &enable);
    
    http_enable_protocol_analysis(enable);
    http_set_session_callback(handle_http_event, nullptr);
    logger_info("zjx--Native Enable Http Analysis");
    return nullptr;
}

// 设置签名密钥
static napi_value nativeSetHttpSecretKey(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    char key[256] = {0};
    size_t len;
    napi_get_value_string_utf8(env, args[0], key, sizeof(key), &len);
    
    http_secret_key = key;
    logger_info("zjx--Native Set Http SecretKey");
    return nullptr;
}

// 监听HTTP会话
static napi_value nativeSetHttpEventCallback(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    napi_valuetype valuetype;
    napi_typeof(env, args[0], &valuetype);
    if (valuetype != napi_function) {
        napi_throw_error(env, nullptr, "Callback must be a function");
        return nullptr;
    }
    
    if (http_event_callback) {
        napi_release_threadsafe_function(http_event_callback, napi_tsfn_abort);
    }
    
    napi_value httpCallbackName;
    napi_create_string_utf8(env, "HTTP Event Callback", NAPI_AUTO_LENGTH, &httpCallbackName);
    napi_create_threadsafe_function(
        env,
        args[0],
        nullptr,
        httpCallbackName,
        0,
        1,
        nullptr,
        nullptr,
        nullptr,
        http_event_handler,
        &http_event_callback
    );
    logger_info("zjx--Native Set Http Event Callback");
    return nullptr;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"start", nullptr, nativeStart, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"enableUdp", nullptr, nativeEnableUdp, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"disableUdp", nullptr, nativeDisableUdp, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"stop", nullptr, nativeStop, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"addIPRange", nullptr, nativeAddIPRange, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"clearIPRanges", nullptr, nativeClearIPRanges, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setIPRangeFilter", nullptr, nativeSetIPRangeFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setRetryConfig", nullptr, nativeSetRetryConfig, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setPacketCallback", nullptr, nativeSetPacketCallback, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"getPacketProtocol", nullptr, nativeGetPacketProtocol, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setLocalDNS", nullptr, nativeSetLocalDNS, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setUpstreamDNS", nullptr, nativeSetUpstreamDNS, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"addGateway", nullptr, nativeAddGateway, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"getGateways", nullptr, nativeGetGateways, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"removeGateway", nullptr, nativeRemoveGateway, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"registerResource", nullptr, nativeRegisterResource, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"requestResource", nullptr, nativeRequestResource, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setDnsEventCallback", nullptr, nativeSetDnsEventCallback, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setGatewayEventCallback", nullptr, nativeSetGatewayEventCallback, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"updateGatewayLatency", nullptr, nativeUpdateGatewayLatency, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"dnsResolveLocal", nullptr, nativeDnsResolveLocal, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"gatewaySelect", nullptr, nativeGatewaySelect, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"resourceLocate", nullptr, nativeResourceLocate, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"enableHttpAnalysis", nullptr, nativeEnableHttpAnalysis, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setHttpSecretKey", nullptr, nativeSetHttpSecretKey, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setHttpEventCallback", nullptr, nativeSetHttpEventCallback, nullptr, nullptr, nullptr, napi_default, nullptr}
    };
    napi_define_properties(env, exports, sizeof(desc)/sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "tun2sock",
    .nm_priv = nullptr,
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterTun2sockModule(void) {
    napi_module_register(&demoModule);
}